#pragma once
#include <cerrno>
#include<string.h>
#include <cstdint>
#include<iostream>
#include <string>
#include<memory>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include "ThreadPool/Task.hpp"
#include "ThreadPool/Thread.hpp"
#include"ThreadPool/ThreadPool.hpp"
#include "ThreadPool/log.hpp"

class TcpServer
{
public:
    TcpServer(uint16_t port,std::string ip="")
    :_port(port),_ip(ip)
    ,_sock(-1)
    {

    }
    void initServer()
    {
        _sock=socket(AF_INET,SOCK_DGRAM,0);
        if(_sock < 0)
        {
            logMessage(FATAL, "%d:%s",errno,strerror(errno));
            exit(1);
        }
        struct sockaddr_in server;
        bzero(&server,sizeof(server));
        server.sin_family=AF_INET;
        server.sin_port=htons(_port);
        server.sin_addr.s_addr=inet_addr(_ip.c_str());
        if(bind(_sock,(struct sockaddr*)&server,sizeof(server)) < 0)
        {
            logMessage(FATAL,"%d:%s",errno,strerror(errno));
            exit(2);
        }
        logMessage(NORMAL,"init server succeed");
        if(listen(_sock,gbackLog) < 0)
        {
            logMessage(FATAL, "%d:%s",errno,strerror(errno));
            exit(3);
        }
    }
    void start()
    {
        _thread_ptr->run();
        while(true)
        {
            struct sockaddr_in server;
            socklen_t len=sizeof(server);
            int serversock=accept(_sock, (struct sockaddr*)&server, &len);
            if(serversock < 0)
            {
                logMessage(FATAL, "%d:%s",errno,strerror(errno));
                exit(1);
            }
            std::string server_ip=inet_ntoa(server.sin_addr);
            uint16_t server_port=ntohs(server.sin_port);
            Task task;
            _thread_ptr->pushTask(task);
        }
    }
    ~TcpServer(){
        //线程池的基本接口
    }
private:
    const int gbackLog=20;
    std::string _ip;
    uint16_t _port;
    int _sock;
    std::unique_ptr<ThreadPool<Task>> _thread_ptr;
};
// class TcpServer
// {
// public:
//     TcpServer(uint16_t port,std::string ip="")
//     :_port(port),_ip(ip)
//     ,_sock(-1)
//     {

//     }
//     bool initServer()
//     {
//         _sock=socket(AF_INET, SOCK_DGRAM, 0);
//         if(_sock < 0)
//         {
//             logMessage(FATAL,"%d:%s",errno,strerror(errno));
//             exit(1);
//         }
//         struct sockaddr_in server;
//         bzero(&server,sizeof(server));
//         server.sin_family=AF_INET;
//         server.sin_port=htons(_port);
//         server.sin_addr.s_addr=inet_addr(_ip.c_str());
//         if(bind(_sock,(struct sockaddr*)&server,sizeof(server)) < 0)
//         {
//             logMessage(FATAL, "%d:%s",errno,strerror(errno));
//         }
//         logMessage(NORMAL, "bind() success");
//         if(listen(_sock, gbackLog) < 0)
//         {
//             logMessage(FATAL,"%d:%s",errno,strerror(errno));
//             exit(2);
//         }
//     }
//     // void thread_start()
//     // {
//     //     ThreadData* td=new ThreadData();
        
//     // }
//     void start()
//     {
//         _thread_ptr->run();
//         while(true)
//         {
//             struct sockaddr_in server;
//             socklen_t len=sizeof(server);
//             int serversock=accept(_sock, (struct sockaddr*)&server, 
//             &len);
//             if(serversock < 0)
//             {
//                 logMessage(FATAL, "%d:%s",errno,strerror(errno));
//                 exit(3);
//             }
//             uint16_t server_port=ntohs(server.sin_port);
//             std::string server_ip=inet_ntoa(server.sin_addr);
//             //这里之所以要获取套接字是因为执行任务需要套接字
//             Task task;
//             _thread_ptr->pushTask(task);
//         }
//     }
//     ~TcpServer()
//     {

//     }
// private:
//     const int gbackLog=20;
//     uint16_t _port;
//     std::string _ip;
//     int _sock;
//     std::unique_ptr<ThreadPool<Task>> _thread_ptr;
// };
// // class TcpServer
// // {
// // public:
// //     TcpServer(uint16_t port,std::string ip="")
// //     :_sock(-1),_port(port)
// //     ,_ip(ip)
// //     ,_thread_ptr(ThreadPool<Task>::getThreadPool())
// //     {

// //     }
// //     void initServer()
// //     {
// //         _sock=socket(AF_INET,SOCK_DGRAM,0);
// //         if(_sock < 0)
// //         {
// //             logMessage(FATAL,"%s %s",errno,strerror(errno));
// //             exit(1);
// //         }
// //         logMessage(NORMAL,"create socket success,socke :%d",_sock);
// //         struct sockaddr_in server;
// //         memset(&server,0,sizeof(server));
// //         server.sin_family=AF_INET;
// //         server.sin_port=htons(_port);
// //         server.sin_addr.s_addr=inet_addr(_ip.c_str());
// //         if(bind(_sock,
// //         (struct sockaddr*)&server, sizeof(server)) < 0)
// //         {
// //             logMessage(FATAL,"%d:%s",errno,strerror(errno));
// //             exit(2);
// //         }
// //         //这里是需要在绑定之后再进行监听
// //         if(listen(_sock, gbacklog) < 0)
// //         {
// //             logMessage(FATAL,"%d:%s",errno,strerror(errno));
// //             exit(3);
// //         }
// //         logMessage(NORMAL, 
// //         "init server success");
// //     }
// //     void start3()
// //     {
// //         _thread_ptr->run();
// //         while(true)
// //         {
// //             struct sockaddr_in server;
// //             socklen_t len=sizeof(server);
// //             int serversock=accept(_sock,(struct sockaddr*)&server, 
// //             &len);
// //             if(serversock < 0)
// //             {
// //                 logMessage(FATAL,"%d:%s",errno,strerror(errno));
// //                 exit(2);
// //             }
// //         }
// //     }
// //     void start2(){
// //         _thread_ptr->run();
// //         while(true)
// //         {
// //             struct sockaddr_in server;
// //             socklen_t len=sizeof(server);
// //             int serversock=accept(_sock,(struct sockaddr*)&server, 
// //             &len);
// //             if(serversock < 0)
// //             {
// //                 logMessage(FATAL,"%d:%s",errno,strerror(errno));
// //                 exit(1);
// //             }
// //             uint16_t server_port=ntohs(server.sin_port);
// //             std::string server_ip=inet_ntoa(server.sin_addr);
// //             logMessage(NORMAL,"link success");
// //             Task task;
// //             _thread_ptr->pushTask(task);
// //         }
// //     }
// //     void start()
// //     {
// //         //这里是单个进程服务版本
// //         _thread_ptr->run();
// //         while(true)
// //         {
// //             struct sockaddr_in client;
// //             socklen_t len=sizeof(client);
// //             int serversock=accept(_sock, 
// //             (struct sockaddr*)&client, 
// //             &len);
// //             if(serversock < 0)
// //             {
// //                 logMessage(FATAL, 
// //                 "%d:%s",errno,strerror(errno));
// //                 exit(2);
// //             }
// //             uint16_t client_port=ntohs(client.sin_port);
// //             std::string client_ip=inet_ntoa(client.sin_addr);
// //             logMessage(FATAL, 
// //             "%d:%s",errno,strerror(errno));
// //             //这里的任务需要重新封装
// //             Task task;
// //             //Task task(serversock,client_ip,client_port,nullptr);
// //             _thread_ptr->pushTask(task);
// //         }
// //     }
// //     ~TcpServer(){

// //     }
// // private:
// //     const static int gbacklog=20;
// //     uint16_t _port;
// //     std::string _ip;
// //     int _sock;
// //     std::unique_ptr<ThreadPool<Task>> _thread_ptr;
// // };